Skip to content

Drift-kinetic island/layer solver#318

Draft
logan-nc wants to merge 66 commits into
developfrom
feature/islands
Draft

Drift-kinetic island/layer solver#318
logan-nc wants to merge 66 commits into
developfrom
feature/islands

Conversation

@logan-nc

@logan-nc logan-nc commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Design plan (docs only) for Islands, a new GPEC submodule (src/Islands/): a steady-state, multi-species drift-kinetic solver for the resonant island/layer region that returns the growth moment Δ_cos(w, ω; p) and torque moment Δ_sin(w, ω; p) for arbitrary parameters — replacing the sum of regime-specific Modified Rutherford Equation terms with a single calculation, and in its small-amplitude limit reducing to the linear layer response so that error-field shielding, penetration, seeded-NTM onset, and island saturation become faces of one solution manifold.

Draft: this PR lands the design docs (docs/src/islands/, module conventions in src/Islands/CLAUDE.md) and the drift-kinetic reference library, revised against the Imada / Dudkovskaia / Leigh source set. No solver code yet.

🤖 Generated with Claude Code

logan-nc and others added 4 commits July 7, 2026 15:31
…an under src/islands

Design bundle for ISLET (Integrated SoLver for Evolving Tearing), a planned
steady-state multi-species drift-kinetic solver for the resonant island/layer
region, generalizing the Modified Rutherford Equation the way SLAYER generalized
linear layer theory. Revised against the full Imada/Dudkovskaia/Leigh reference
set in docs/resources/Drift_Kinetic_Island_References (see REVISION-2026-07-07).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uthor-title convention

Renames the nine PDFs under docs/resources/Drift_Kinetic_Island_References to the
YEAR-Author-Title convention used by the rest of docs/resources, and extends the
.gitignore resources-PDF negation to subdirectories (!docs/resources/**/*.pdf) so
these tracked references match the existing docs/resources/*.pdf policy. Syncs the
filename references in the ISLET reference-library doc (docs/08).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e convention)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n into in-repo layout

Drop the working acronym ISLET in favour of the plain module name Islands, and
record the module-naming convention (simple intuitive names, not standalone-code
acronyms) in the repo-root CLAUDE.md.

Reconcile the design bundle from its standalone-package assumptions into the
in-repo layout:
- module conventions   -> src/Islands/CLAUDE.md
- overview             -> docs/src/islands/index.md
- design docs 00-08    -> docs/src/islands/design/
- Physics Book / state / derivations / papers / notes / LOG / QUESTIONS
                       -> docs/src/islands/{,state,derivations,papers,notes}
- benchmarks + figures -> benchmarks/islands/{,figures}
- verify harness       -> src/Islands/verify/
- tests                -> test/runtests_islands_*.jl (top-level test/)
- regression cases     -> integrated under regression-harness/ (islands_*)

Islands is a submodule of the GeneralizedPerturbedEquilibrium package (no separate
Project.toml), not a standalone subpackage; docs/03/06 updated accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@logan-nc logan-nc changed the title Islands: drift-kinetic island/layer solver — design plan Drift-kinetic island/layer solver Jul 8, 2026
@logan-nc logan-nc self-assigned this Jul 8, 2026
@logan-nc logan-nc added enhancement New feature or request WIP Work in progress labels Jul 8, 2026
logan-nc and others added 22 commits July 8, 2026 00:11
… infrastructure

Stand up the Islands submodule and the infrastructure the autonomous-run
protocol (design doc 06) assumes:
- src/Islands/Islands.jl (module Islands, skeleton) wired into the package
- docs/src/islands/LOG.md + QUESTIONS.md (session memory + blocker queue; Q1
  records that julia is not on the automation shell PATH)
- .claude/settings.json + hooks (guard-bash PreToolUse, stop-check Stop) for
  unattended dontAsk runs; physics-verifier subagent as the [VERIFY] backstop
- docs/src/islands/design/M1-launch-prompt.md (the milestone contract fed to
  the overnight loop)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…docs

The exported Islands module carries a docstring, which checkdocs=:exports
requires be covered in the manual. Add docs/src/islands.md with an @autodocs
block and wire it into make.jl (API Reference), matching the other submodule
pages. Fixes the missing_docs docs-build failure introduced by the module stub.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tings.json

/doctor flagged two deny rules as skipped: the :* prefix wildcard is only valid
at the end of a pattern. Rewrite them with a mid-pattern wildcard so the rules
load and again restrict the protected-branch pushes for any remote or flags.
A loaded OMFIT module leaks the conda env lib dir onto LD_LIBRARY_PATH, shadowing
Julia's bundled artifacts (CHOLMOD, glib/Cairo/GR) and producing false 'broken
build' blocks in the Stop hook. Strip the var for the julia smoke check via
env -u; this is a no-op on a clean shell and in CI.
M1 needs forward-mode AD for the JVP/AD-compatibility checks (design
docs/src/islands/design/04-numerics.md §9). Adds ForwardDiff to Project.toml
(already present transitively in the manifest); removes nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ck + verify harness

Land the milestone-M1 numerical skeleton (design 03 §1-2, 04; ladder A1/A2),
structure only — no [VERIFY] physics coefficients assigned in src/.

- phasespace/PhaseSpace.jl: the (x, ξ, y, E, σ) grids with layer-clustered maps.
  Fourier spectral ∂ξ; Fornberg high-order finite differences for ∂x/∂y on
  sinh-stretched grids (per-derivative window widths so D1 and D2 are both
  4th-order including boundaries); composite-Simpson quadrature weights;
  Gauss-Laguerre energy nodes. Pure numerics.
- operators/Operators.jl: AbstractTerm + apply! + residual! and the term structs
  of 03 §2 (ParallelStreaming, MagneticDrift with the :original/:improved toggle,
  ExBDrift as the (x,ξ) Poisson bracket, Collisions, GradientDrive, PerpTransport
  and RadiationSink L4 stubs, Quasineutrality field residual). Every physics
  coefficient is a supplied data field, never a literal; allocation-free and
  generic over eltype so ForwardDiff duals flow through.
- verify/Verify.jl: manufactured-solution (MMS) + AD-vs-finite-difference JVP
  harness, plus allocation probes. Manufactured coefficients are arbitrary
  order-unity test values (not physics), exercising the discretization only.
- Islands.jl: wire the three submodules.

physics-verifier: PASS (no [VERIFY]-policy violation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…to runtests

test/runtests_islands_grids.jl and test/runtests_islands_operators.jl, included
in test/runtests.jl:

- A1 per-operator MMS: 4th-order convergence for the ∂x/∂y differential terms,
  machine precision for the Fourier ∂ξ (drift) term; assembled kinetic residual
  converges at 4th order.
- A2: forward-mode-AD JVP of the (nonlinear) assembled residual matches the
  central finite-difference directional derivative to ~1e-9.
- Allocation regression: every apply! and residual! hot path allocates 0 bytes.
- Grid unit tests: Fourier exactness, mapped-FD order, Simpson/Gauss quadrature,
  layer-clustered packing, IslandGrid assembly and input validation.

All 53 Islands tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…path)

- docs/src/islands.md: document the M1 skeleton (PhaseSpace/Operators/Verify),
  restating the structure-only [VERIFY] discipline.
- LOG.md: M1 session entry (what moved / blocked / next).
- QUESTIONS.md: Q1 RESOLVED — julia is at the ncl2128 software dir and must be
  invoked with a clean LD_LIBRARY_PATH (OMFIT contamination); used here to run
  the suite locally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Set up the next milestone (M2 — L0 solve machinery) for the autonomous loop,
mirroring the M1 launch-prompt bootstrap.

- docs/src/islands/design/M2-launch-prompt.md: the M2 milestone contract. Scope
  = full L0 solve machinery (solvers/, moments/, frames/, fields/, species/,
  neoclassical-matching BCs) as AD-compatible allocation-free structure with every
  physics coefficient a [VERIFY]-gated parameter. DoD = the physics-free structural
  gates (A5 null, assembled solve-MMS, A8 y_c conditioning, A4 conservation, A3
  parity, A7 ⟨∂²h/∂x²⟩=0) + suite + PR + Paper-I OUTLINE + the clearance queue.
  The York gates (B5a/b/c, B2, B4) are explicitly OUT — they need human-cleared
  physics; reaching one by hardcoding is a policy violation, not completion.
- QUESTIONS.md: seed the parallel-human clearance queue — Q2 (ratify D7/D8),
  Q3 (clear the L0 [CHECKED] coefficient set with exact cites), Q4 (open [VERIFY]s:
  the psi-tilde q_s'/q_s typo, B5a collisionality, acquire WCHH96 + Park 2022).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the overnight-loop framing (dontAsk/--continue header, unattended language,
Stop-hook exit-criteria) — M2 is driven interactively via /goal in auto mode.
Blocked coefficients are surfaced to the user to clear live rather than only
parked in QUESTIONS.md. The contract (scope, DoD, [VERIFY] hard rule, gated York
gates) is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ylov solver

Matrix-free GMRES backend for the L0 solve (design docs/src/islands/design/04-numerics.md $5, $9).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…es, fields, moments

Land the Level-0 solve structure (design 03 §1-3, 04 §3-5; M2 contract), every
physics coefficient a supplied [VERIFY]-gated parameter — no literal in src/:

- solvers/Solvers.jl: matrix-free Newton-Krylov (Krylov.jl GMRES on a
  preallocated ForwardDiff JVP operator; Eisenstat-Walker forcing; backtracking
  line search; convergence on both norm and max-norm per 04 §5), YBlockJacobi
  physics-block preconditioner skeleton with TSVD-regularized pencil solves
  (the explicit y_c treatment of 04 §3), dense tiny-grid debug Jacobian, and a
  pseudo-arclength continuation scaffold with fold detection from day one.
- species/Species.jl: Species{AbstractBackground}, Maxwellian/SlowingDown,
  Bulk/Trace roles, validation + trace-criteria check (warn, never degrade) —
  the D3 first-class species plumbing (02 §1).
- frames/Frames.jl: Level0Parameters input vector (01 §5) and the frame
  conversion FORMS with every sign/normalization a NaN-defaulted gated
  FrameConvention field — an un-cleared convention poisons results instead of
  guessing (QUESTIONS Q3).
- fields/Fields.jl: Q(Ω)/h(Ω) flattened-electron closure structure (prefactor
  supplied), the coefficient-free A7 identity ⟨∂²h/∂x²⟩_Ω = 0, and the
  NaN-gated ElectronClosure constant set.
- moments/Moments.jl: J̄_∥ assembly from charge-scaled weighted moments,
  Δ_cos/Δ_sin projections with REQUIRED gated prefactors (ψ̃ open [VERIFY],
  sin normalization unpinned — QUESTIONS Q4), Ω label + ⟨·⟩_Ω average +
  channel-split diagnostics (pinned half-width convention).
- operators/: PitchAngleDiffusion in mimetic divergence form (exact discrete
  particle conservation + entropy sign, ladder A4), FarFieldConditions
  matching BCs (never bare Neumann, 01 §3), weighted_moment!, flat-index
  helpers; IslandGrid now records y_c for the A8 monitor.
- verify/: solve-level MMS + zero-drive configurations (A5/A1-solve) and the
  yc_block_sigma_min conditioning monitor (A8, the L23 §4.2 silent-noise
  regression tripwire).

All new kernels pass a --check-bounds=yes run (M1 lesson).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…/A8 + solve-MMS)

test/runtests_islands_solve.jl (67 tests, wired into runtests.jl):
- A5 zero-drive null: residual exactly machine zero at g ≡ 0; Newton falls back
  to the zero state from a perturbation.
- A1-solve: assembled Newton-Krylov solve recovers the manufactured state at
  design order (observed 3.98 on the nx = 17→33 pair).
- A4: exact discrete particle conservation (≲1e-11) + entropy sign of the
  mimetic pitch-angle operator; allocation-free apply!.
- A3: Δ_cos even / Δ_sin odd under ξ-reflection, spectrally exact projections.
- A7: ⟨∂²h/∂x²⟩_Ω = 0 to 1e-10 across Ω and prefactors (coefficient-free).
- A8: y_c-block σ_min monitor is finite/positive and detects an artificially
  singularized pencil.
- Preconditioner gate: YBlockJacobi cuts GMRES iterations >2× at identical
  solutions; far-field BC rows; pseudo-arclength fold detection; species +
  gated-frames plumbing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…ctural regression case

- benchmarks/islands/ (+ figures/): the docs/05 B-ladder scripts B2 (large-w
  limits), B4 (polarization ω_E structure), B5a/b/c (York threshold triangle) —
  all SKIPPED, each naming the QUESTIONS.md entries (Q2-Q4) whose human
  clearance un-gates it. Un-skipping by filling in a coefficient is the
  forbidden action; the scripts say so.
- regression-harness: new computed case islands_l0_structural tracking the
  structural numbers that silently move if the discretization/solver/quadratures
  drift — solve-MMS error + Newton/GMRES iteration counts (nx=17), the A7
  closure identity, and the A8 y_c-block sigma_min. Verified locally:
  err=5.254e-2, 6 Newton / 1210 GMRES, A7=8.0e-17, sigma_min=0.1139.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
- docs/src/islands/papers/paper-1/OUTLINE.md: the Level-0 figure contract
  (docs/07 §3), claims → figures → ladder IDs. C1-C3 (discretization order,
  solver conditioning, conservation structure) are green as CI artifacts;
  C4-C8 (neoclassics, large-w limits, the York triangle, the Δ_pol(ω_E)
  reversal, the L23 electron-Δ_pol question) are gated on QUESTIONS Q2-Q4.
- docs/src/islands.md: M2 status (all seven submodules, gating summary).
- LOG.md: M2 session entry, including the solve-well-posedness lesson (generic
  y-diffusion without BCs is unstable; the mimetic degenerate form + far-field
  x-BCs are the correct structure).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…docs missing_docs)

Documenter's checkdocs=:exports requires every exported docstring in the
package (including submodules) to appear in a page; the islands.md @autodocs
block only listed the top-level Islands module, so the PhaseSpace/Operators/
Verify exports failed the docs build. Add per-submodule @autodocs sections.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
logan-nc and others added 30 commits July 11, 2026 14:40
…ned-off coefficient)

Human sign-off 2026-07-11 of the psi-tilde derivation (D7). Records the clearance
and un-gates the cleared relation:

- docs/01 §1: [CHECKED: I19 Eq.5...] -> [CLEARED: sign-off 2026-07-11, derivation
  link]; the psi-tilde [VERIFY] marked RESOLVED (I19 published typo; physical
  form q_s'/q_s).
- Moments.island_flux_amplitude(; w_psi, dq_dpsi, q_s) = (w_psi^2/4)(q_s'/q_s),
  anchored to the derivation, with 4 tests (value, w^2 scaling, half-width
  round-trip, q_s=0 guard). 71 islands-solve tests green.
- delta_moments prefactors stay required/gated (mu_0 R + sin-normalization pin
  are separate open items); Frames/Fields NaN-gates untouched.

physics-verifier: PASS (formula matches signed-off derivation; clearance recorded,
not a silent promotion; nothing else un-gated).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…iginal/:improved toggle (D7)

Second M2b derivation-lane chapter. Independent re-derivation of the orbit-
averaged magnetic drift frequency from the guiding-centre drift (I19 Eq.8) and
p_phi conservation:

  omega_hat_D = (sigma v_hat/(1+eps))[ (1/L_hat_q)<sqrt(1-yb)/b>
                - (1/2)<(1/L_hat_B)(2-yb)/(b sqrt(1-yb))> ]

Two physical pieces: (1) the drift-orbit radial width x_D = rho_hat_theta_i
(sigma v_hat/(1+eps)) sqrt(1-yb)/b coupled to the safety-factor shear (1/L_q);
(2) the grad-B drift from dB/dpsi (1/L_B). The :original/:improved toggle is the
treatment of dB/dpsi: D21 Eq.(A2) gives dB/dpsi = -(B_phi/R_0^2 B_theta) cos theta
(low beta), so the cos theta orbit-averages to O(eps) => :improved sets
L_hat_B^-1 = 0; :original keeps it finite. This toggle is the highest-impact
physics item (the T2 ~x6 threshold-width differential; absolute 8.73->1.46 rho_bi
is T4/audit-gated, per D9).

Cross-checks (all first-hand): I19 Eq.(32), D21 Eq.(B1) [with the identity
V_par + lambda V^2/(2 V_par) = V(2-lambda B)/(2 sqrt(1-lambda B))], D21 Eq.(A2).
No discrepancy (unlike the psi-tilde typo).

physics-verifier: PASS (algebra (a)-(d) verified by hand, D21-B1 reconciliation
confirmed, provenance clean, no src/ change; MagneticDrift.c_D stays gated).
Docs-only; local docs build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…le; drift-model toggle usable)

Human sign-off 2026-07-11 of the omega-hat-D derivation (D7). Records the
clearance (docs/01 §2.1: [CHECKED] -> [CLEARED]) and implements the cleared
coefficient:

- New src/Islands/coefficients/Coefficients.jl: the home for human-cleared L0
  physics coefficient builders (M2b fill-ins). magnetic_drift_frequency(...)
  computes omega-hat-D = (sigma v_hat/(1+eps))[inv_Lq A - (1/2) inv_LB G] via the
  orbit-average brackets A=<sqrt(1-yb)/b>, G=<(2-yb)/(b sqrt(1-yb))> (QuadGK;
  passing full-circuit, trapped bounce-integral with the integrable turning-point
  singularity). variant=:improved forces inv_LB=0 (D21 proxy). Wired into
  Islands.jl.
- 13 tests: eps->0 analytic limit (A->sqrt(1-y), G->(2-y)/sqrt(1-y)), the toggle
  (:improved == :original with L_B=0), sigma-odd / v_hat-linear prefactor,
  trapped finiteness, forbidden-y and bad-variant guards. 84 islands-solve tests
  green. The toggle is a large effect at the test point (grad-B nearly cancels
  the shear term) -- the mechanism behind the ~x6 threshold differential.

physics-verifier: PASS (formula matches signed-off derivation; clearance recorded;
trapped branch sound; Frames/Fields NaN-gates and Moments prefactors untouched).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…deflection frequency + nu_star (D7)

Third M2b derivation-lane chapter. Independent re-derivation of the Level-0
momentum-conserving pitch-angle (Lorentz) collision operator (I19 Eq.9), the
deflection frequency (I19 Eq.11), and the nu_star normalization (L23 Eq.2.3.40):

- The pitch operator is Lorentz scattering in self-adjoint form
  w^-1 d_lambda(P d_lambda) with diffusivity P(lambda)=lambda sqrt(1-lambda B)
  and measure w=B/sqrt(1-lambda B); the change of variables from the pitch
  cosine derives the exact 2 nu_jj prefactor. This is the same divergence form
  the mimetic PitchAngleDiffusion discretizes (conservation gate A4).
- Deflection frequency nu_jj = nu_tilde[phi(v_hat)-G(v_hat)]/v_hat^3
  (Chandrasekhar), with the :chandrasekhar/:vcubed sub-toggle. Low-v: phi-G ->
  (4/3 sqrt-pi) v_hat (LINEAR) so nu_jj ~ 1/v_hat^2 diverges -- the
  "nu_tilde ~ u^-2 divergence" of docs/01 §2.3 motivating the analytic average.
- nu_star = nu_jj Rq/(eps^3/2 v_th) normalization.

Two sub-items honestly DEFERRED (not asserted, policy rule 4): the analytic
<nu_hat_ii>_u constant (L23 Eq.4.1.6, its own short derivation) and the
discretized diffusivity profile (numerics, ties to A4).

Review caught two errors, both fixed before sign-off: the §3 low-v limit
(phi-G is linear, not cubic -> nu_jj diverges, not finite) -- caught
independently by me and the physics-verifier -- and a §2 factor-of-2 in the
change of variables (now derives the exact 2 nu_jj). Docs-only; local docs build
green. Awaiting human sign-off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
… src (P(lambda), deflection frequency)

Human sign-off 2026-07-11 of the collision-operator derivation (D7). Records the
clearance (docs/01 §2.3: [CHECKED] -> [CLEARED] for the operator structure,
deflection frequency, and nu_star; the <nu_hat_ii>_u constant stays [CHECKED]-
gated as a deferred sub-item) and un-gates the cleared building blocks:

- Coefficients.pitch_diffusivity(lambda, B) = lambda sqrt(1-lambda B): the
  Lorentz operator's self-adjoint diffusivity P (feeds conservative_pitch_operator;
  vanishes at both endpoints, preserving the A4 gate).
- Coefficients.deflection_frequency(v_hat; model): nu_jj = nu_tilde[phi-G]/v_hat^3
  (:chandrasekhar) or nu_tilde/v_hat^3 (:vcubed), phi via QuadGK, G Chandrasekhar.
- 11 tests: P endpoints/positivity/domain; deflection high-v (-> nu_tilde/v_hat^3,
  with the slow 1-1/2v_hat^2 approach) and low-v (-> (4/3 sqrt-pi)/v_hat^2
  divergence, the derived linear phi-G limit); chandrasekhar < vcubed at low v;
  model/domain guards. 96 islands-solve tests green.

The full discretized/orbit-averaged PitchAngleDiffusion assembly and the
<nu_hat_ii>_u momentum-restoring constant remain deferred (docs/01 §2.3 note).

Derivation physics-verifier: PASS (after review caught + fixed a low-v limit
error and a change-of-variables factor). Un-gate implements the just-verified
cleared forms directly, validated by the eps/velocity-limit tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…a) + amplitude (D7); fix Coefficients docs coverage

Fourth M2b derivation-lane chapter (awaiting sign-off). Independent re-derivation
of the flattened-electron profile function and its amplitude:

- The closure constraint <d2h/dx2>_Omega = 0 (the A7 identity) gives the ODE
  2 h'' <Omega+cos xi>_Omega + h' = 0; with <Omega+cos xi>_Omega = Q/(2Q')
  (Q=(1/2pi)∮sqrt(Omega+cos xi)dxi) this integrates to h'(Omega) = C/Q(Omega) --
  i.e. h = Theta(Omega-1) C ∫_1^Omega dOmega'/Q. The already-green A7 gate IS this
  closure constraint.
- Far-field matching h -> x (Q -> sqrt(Omega)) fixes the amplitude
  C = w_psi/(2 sqrt2), matching I19 Eq. 18 exactly.
- The I19 Eq. 22 flow-relation structure is presented; the two constants
  k ~= -1.173 (Hirshman-Sigmar) and the 1.46 in f_p = 1 - 1.46 sqrt(eps) are
  honestly DEFERRED (their own short derivations), not asserted.

physics-verifier: PASS (algebra (a)-(e) verified first-hand incl. h'=C/Q and the
C=w_psi/2sqrt2 matching; provenance clean; deferred constants not asserted).

Also FIXES the docs build (was red since the omega-D commit): the new
Coefficients module's exported docstrings were not in the manual; added its
@autodocs section to islands.md (checkdocs=:exports). Local docs build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…ts.h_amplitude)

Human sign-off 2026-07-11 of the electron-closure derivation (D7). Records the
clearance (docs/01 §2.4: h(Omega) form + amplitude [CLEARED]; the flow constants
k ~= -1.173 and f_p's 1.46 stay [CHECKED]-gated as deferred sub-items) and
un-gates the cleared amplitude:

- Coefficients.h_amplitude(w_psi) = w_psi/(2 sqrt2): the flattened-electron
  profile prefactor C, derived from the flattening constraint (h'=C/Q) + far-
  field matching h->x. Feeds Fields.h_profile's prefactor.
- 3 tests: the amplitude value; the far-field asymptote
  h_profile(Omega; C) -> (w_psi/sqrt2)(sqrt(Omega)-1) (a real check of the §3
  derivation + the Q->sqrt(Omega) asymptotics); ElectronClosure k/f_p stay NaN.
  98 islands-solve tests green.

Derivation physics-verifier: PASS (h'=C/Q ODE and C=w_psi/2sqrt2 matching
verified first-hand). Un-gate is a one-line cleared relation; far-field test
validates it physically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…), arbitrary tau (D7)

Fifth M2b derivation-lane chapter (awaiting sign-off). Independent re-derivation
of the Level-0 quasineutrality closure from the ion/electron density moments:

- Ion moment n_i = n0(1-ePhi/T_i) + n0'(psi-psi_s) + dn_bar_i (from f_i, I19 Eq.23).
- Electron moment n_e = n0(1+ePhi/T_e) + n0' h(Omega) (flattened closure; the
  v_par-odd term vanishes).
- n_i=n_e => Phi_hat = tau/(tau+1)[dn_bar_i/n0 + L_n0^-1(x - h_hat)]. The
  denominator (tau+1)/tau is the SUM of ion+electron adiabatic shielding
  responses (1/T_i + 1/T_e) -- the origin of the "2" in 1/(2 L_n0). At tau=1 this
  reduces exactly to I19 Eq. A.11 [dn_i/n0 + x - h_hat]/(2 L_n0), and the
  derivation adds the arbitrary-tau generalization docs/01 §3 asks for.

Initial pass surfaced a structural question (dn_i inside vs outside the 1/L_n0
factor); read I19 Eq. A.11 first-hand (print p.11) and resolved it: no
discrepancy -- I19's normalized dn_i = L_n0 * (raw moment), a definitional
convention, flagged openly. The invariant x-h_hat structure and the tau=1
coefficient match I19 exactly with nothing tuned.

physics-verifier: PASS (algebra a-e verified first-hand incl. the (tau+1)/tau
factor and tau=1 reduction; provenance clean, no src/ change; dn_i normalization
honestly a convention). Local docs build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…tau+1)); triple-checked dn convention

Human sign-off 2026-07-11 of the quasineutrality-closure derivation (D7), after
an independent triple-check of the dn normalization. Records the clearance
(docs/01 §3) and un-gates the coefficient:

- Coefficients.quasineutrality_coefficient(tau) = tau/(tau+1): the closure
  coefficient (sum of ion+electron adiabatic responses; -> 1/2 at tau=1).
- 4 tests: tau=1 -> 1/2, tau=2 -> 2/3, tau->inf -> 1, positivity guard.
  102 islands-solve tests green.

Triple-check resolution: the (x - h_hat) structure and the coefficient match
I19 Eq. A.11 exactly; the only difference from I19's delta_n_i is a scaling by
L_n0, which is PHYSICALLY FORCED (the raw moment is gradient-driven,
delta_n_bar_i ~ L_n0^-1). Decisively, the code uses the RAW-MOMENT form
(delta_n_bar_i = velocity_moment! output), so I19's delta_n_i normalization is a
cross-check nuance only and does not enter src -- the un-gate is unambiguous.
Also derived the arbitrary-tau generalization docs/01 §3 asked for.

physics-verifier: PASS (derivation algebra a-e verified first-hand). Un-gate is a
one-line cleared coefficient.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…tors (D7; sin-normalization pin)

Sixth and final M2b main-derivation chapter (awaiting sign-off). Derives the
output-moment prefactors:

- Delta_cos = Delta_neo = -(mu0 R/2 psi_tilde) ∫∫ Jbar_par cos xi: the growth
  moment matched to the outer Delta' (stationarity Delta' + Delta_neo = 0). The
  prefactor is sourced piece by piece -- mu0 R from parallel Ampere, psi_tilde
  the ALREADY-CLEARED island_flux_amplitude, the 1/2 the adopted Diss19 Eq. 4.12
  Rutherford matching convention (not re-derived from scratch, stated honestly).
- Delta_sin = +(mu0 R/2 psi_tilde) ∫∫ Jbar_par sin xi: the sin normalization has
  no external Delta' to match, so it is a [DERIVED] CHOICE (docs/01 §4 flags it
  as such). Pinned SYMMETRICALLY to cos so Delta_cos + i Delta_sin is the natural
  complex growth+torque moment mapping to the linear-layer Delta(Q) (D1), and the
  A3 parity gate (cos even/sin odd) holds with matched normalization.

physics-verifier: PASS (provenance clean, no src/ change, delta_moments prefactors
stay required/gated; the cos attribution is honest -- adopted Diss19 convention,
not overclaimed; the sin pin is honestly a [DERIVED] decision, consistent with the
green A3 gate). Local docs build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…ation lane complete (6/6 cleared)

Human sign-off 2026-07-11 of the Delta-prefactor derivation (D7). Records the
clearance (docs/01 §4) and un-gates the prefactors:
- Coefficients.delta_moment_prefactors returns (cos=-mu0R/2psi_tilde,
  sin=+mu0R/2psi_tilde); psi_tilde the cleared island_flux_amplitude; feeds
  Moments.delta_moments. Symmetric sin pin ([DERIVED]). 105 tests green.

Completes the M2b derivation lane: all six main L0 coefficient families derived
(D7), signed off, cleared. Deferred sub-constants (<nu_hat_ii>_u, k, f_p) stay
[CHECKED]-gated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…dit + docs infra)

Next milestone after the completed M2b derivation lane: assemble the six cleared
coefficient families into a runnable L0 configuration, produce the D9 input-
completeness audit (docs/09), stand up docs/07 infra (STATE dashboard +
anchor-sync), and scaffold the B-ladder to the assembly. Autonomous-mode: un-gate
nothing new (deferred sub-constants stay gated), draft deferred derivations only
if rigorous else escalate to QUESTIONS, never guess.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…9 deliverable)

Per-source input manifests (I19, D21, D23a/b, L23) auditing which published
NTM-threshold configurations pin down every required input. Type specimen: I19's
run collisionality is internally contradictory (0.01 vs 10^-3) and its Delta'
value is unspecified, so B5a's absolute threshold downgrades to T3 (existence).
L23 (thesis) is the only clean T4 candidate. This is itself a reproducibility
result for Paper I C9. Added to docs nav.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…coeffs wired, gated families escalated)

configure_level0 (src/Islands/configure/Configure.jl) assembles the Level-0
named configuration: it wires the CLEARED coefficient builders onto the operator
stack and takes every uncleared family as a supplied gated input (never guessed).

Cleared wiring (verified faithful):
- c_D from magnetic_drift_frequency, node-for-node (Δ=0.0), with the
  :original/:improved toggle and forbidden-region (y >= 1/b_min) zeroing;
- the pitch-collision shapes from pitch_diffusivity + deflection_frequency;
- the Δ-moment prefactors from delta_moment_prefactors.

Gated/supplied (GatedLevel0Inputs, escalated to QUESTIONS Q5): parallel
streaming, E×B c_E, gradient drive, quasineutrality α, collision magnitude
(⟨ν̂_ii⟩_u/ν_star), orbit-averaged pitch measure, neoclassical far field. The
assembly surfaced a structural gap — the quasineutrality operator lacks the
L̂_n0⁻¹(x−ĥ) field source the cleared closure requires — so no Level-0 physics
run is possible until that lands; M2c delivers the assembly scaffold, verified
STRUCTURALLY (level0_placeholders → Newton-Krylov converges, 5 iters ‖F‖=1.3e-9).

184 islands tests green (new runtests_islands_configure.jl). The y=0 orbit-average
guard was relaxed (y>0 → y>=0): a domain-boundary fix, no y>0 value changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…ding wired to the assembly

#3a STATE dashboard (docs/07 §1.3): Verify.write_state_dashboard + ladder_status
generate docs/src/islands/state/STATE.md (auto-generated, do-not-hand-edit) — the
docs/05 ladder as a status table (8 A-ladder rows green via the test suite; B/C
physics rows gated on QUESTIONS). Nav-wired.

#4 B-ladder scaffolding: benchmarks/islands/benchmark_B{2,4,5}*.jl wired to
Islands.Configure.configure_level0 with a one-line un-skip (const UNGATED = true),
kept skipped on QUESTIONS Q3/Q5. B5 carries the full T2 :original/:improved toggle
scaffold; the physics w_c extraction stays gated on the Q5 far field + QN source.

Also fixes a latent docs-CI breakage: cross-module @refs in the Coefficients
delta_moment_prefactors docstring (island_flux_amplitude, Moments.delta_moments)
do not resolve from the Coefficients module context — converted to plain code
spans. build_docs_local.jl now green. 184 islands tests green.

Remaining M2c: the anchor-sync CI check (#3b) is deferred — it needs the
as-implemented Physics Book chapters + operator anchors (a larger docs deliverable).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…d assembly docs

#3b anchor-sync (docs/07 §1.1): Verify.check_anchor_sync enforces the
bidirectional operator<->docs sync — forward (every AbstractTerm operator is
named by an 'Implemented by:' marker in numerics.md) and reverse (every marker
symbol resolves to a real Islands binding). A new operator without docs, or a
doc naming a deleted symbol, fails the check. Tested with negative controls.

#6 as-implemented docs: numerics.md gains the Level-0 configuration-assembly
section (configure_level0, the cleared wiring vs the Q5-gated families) and
'Implemented by:' markers over the operator stack.

This completes the autonomous portion of M2c: #1 assembly, #2 audit, #3 docs
infra (STATE dashboard + anchor-sync), #4 B-ladder scaffolding, #6 numerics.md.
Remaining M2c is human-gated by design: Q5 (the un-cleared coefficient families
+ the QN operator structural fix) gates any Level-0 physics run and the B-ladder
physics gates; the deferred sub-constants (#5) need a sign-off session.

189 islands tests green; build_docs_local.jl green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…tion (awaiting sign-off)

derivations/passing-fraction.md [DERIVED] derives the electron-closure passing
fraction f_p ~= 1 - 1.46*sqrt(eps) from the effective trapped-fraction integral
(Lin-Liu-Miller / Wesson) in the pinned b(theta) convention, shows the eps->0
all-passing limit analytically (B(2,1/2)=4/3), and NUMERICALLY confirms the
leading coefficient c1 = 1.4624 — matching the sources' quoted 1.46 to 3 s.f.

DRAFTED, NOT CLEARED: f_p stays NaN-gated in Fields.ElectronClosure (no src
change); awaits human sign-off with one open reviewer item (confirm I19 Eq. 22
uses the same effective-trapped-fraction definition). The companion deferred
constants <nu_ii>_u and Hirshman-Sigmar k are left escalated (QUESTIONS Q3/Q5) —
each needs its specific source integrand, not derived speculatively.

This is the M2c #5 deliverable (draft where rigorously possible; escalate the
rest). Wired into the derivations index + nav + QUESTIONS Q5. build_docs_local.jl
green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…y closure (Phi now driven)

Closes the M2c-surfaced quasineutrality structural gap (QUESTIONS Q5). The
closure was signed off in M2b, but Operators.Quasineutrality carried only
R_Phi = M[g] - alpha*Phi (no drive), so the Level-0 potential collapsed to zero.

Implemented the full cleared closure (physics-verifier PASS):
- Operators.Quasineutrality gains an optional source field; apply! adds it
  (R_Phi = M[g] - alpha*Phi + S). Backward-compatible Quasineutrality(alpha).
- Configure.configure_level0 builds alpha = (tau+1)/tau (= 1/quasineutrality_
  coefficient(tau), the reciprocal, = 2 at tau=1) and the drive
  S = inv_Ln0*(x - h(Omega)) via the new Configure.quasineutrality_source, from
  the cleared h_amplitude/h_profile with one width w=w_psi for both Omega and the
  h prefactor (electron-closure.md §3 far-field matching).
- Added inv_Ln0 to Level0Physics; removed alpha from GatedLevel0Inputs and
  level0_placeholders; :quasineutrality moved from gated to cleared.

Verified: max|Phi| ~= 5.7 after the placeholder solve (was ~0). 194 islands
tests green (new testset asserts the reciprocal alpha, the wired source, and a
nonzero solved Phi). Doc-first: docs/01 §3, quasineutrality-closure.md §6,
numerics.md, QUESTIONS Q5 amended. build_docs_local.jl green.

The kinetic Q5 families (streaming, E×B, gradient drive, <nu_ii>_u, pitch
measure, far field) remain gated; a physics threshold still needs those.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…fficients

Re-derived the island-streaming channel from the master DKE (I19 Eq. 32, L23
§2.6-amended trapped mask) — derivations/parallel-streaming.md, human sign-off.
The two coefficients factor EXACTLY into {Omega, g} flux-surface advection:
  a_xi = (inv_Lq/rho_hat_theta_i)*x*Theta(y_c-y)
  a_x  = -(inv_Lq*w^2/4rho_hat_theta_i)*sin(xi)*Theta(y_c-y)
= (inv_Lq*w^2/4rho_hat_theta_i)*Theta*{Omega, .}  -- a coefficient-free structural
check that leaves no freedom (streaming must advect along Omega-contours).
Passing-only via Theta(y_c-y). Normalization (divide by -m*rho_hat_theta_i) chosen
so the already-cleared c_D = omega_hat_D is UNCHANGED.

Implemented as Configure.streaming_coefficients with a new
Level0Physics.rho_hat_theta_i; :streaming moved gated -> cleared; a_xi/a_x removed
from GatedLevel0Inputs and level0_placeholders. physics-verifier PASS (forms,
signs, {Omega,g} structure, c_D unchanged, no guessed coefficient all checked
vs the signed-off derivation). 1494 islands assertions green (new per-node
{Omega,g} structure testset). Doc-first: docs/01 §2, QUESTIONS Q5, numerics.md
§2/§8, derivations index + nav. build_docs_local.jl green.

Cleared now: streaming, drift, collision shapes, quasineutrality field, Delta
prefactors. Still gated (Q5): E×B, gradient drive, <nu_ii>_u, pitch measure,
far field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…= far-field BC)

Read I19 first-hand (Eqs. 8, 23-32) to derive the Level-0 gradient drive.
Finding (derivations/gradient-drive.md, draft): the master orbit-averaged
equation (I19 Eq. 32) is HOMOGENEOUS in G0 -- no interior source term. The
gradient drive enters as the FAR-FIELD BOUNDARY CONDITION: far from the island
G0 -> p_phi*(omega_si^T/omega_ci)*(n'/n)*F_Mi (Eq. 29), the diamagnetic-driven
distribution.

Consequence: Operators.GradientDrive is ZERO at Level 0, and the Q5
'gradient_drive' and 'far_field' items merge into one physical object -- the
diamagnetic far field g_drive = D_dia*x*[1+(vhat^2-3/2)*eta_i]*F_Mi. The
x-linearity, the (vhat^2-3/2)eta_i temperature correction, and the Maxwellian
are cleared structure; the normalized amplitude D_dia bundles the frame
convention Frames.C_dia (still NaN-gated) -- clearing the drive = clearing C_dia
(the ion omega_dia normalization) in the same sign-off.

Nothing entered src/ (docs-only draft). QUESTIONS Q5, derivations index + nav,
LOG updated. build_docs_local.jl green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
Signed off derivations/passing-fraction.md and cleared
Coefficients.passing_fraction(eps) = 1 - 1.4624*sqrt(eps) -- the effective
trapped-fraction coefficient (Lin-Liu-Miller / Wesson), derived analytically
(eps->0 all-passing limit) and numerically confirmed (c1 = 1.4624, matching the
sources' quoted 1.46 to 3 s.f.). Authorizes Fields.ElectronClosure.f_p.

physics-verifier PASS (constant matches the derivation's converged value, form
matches I19 Eq. 22, k correctly stays gated). 1499 islands assertions green
(limits + monotonicity + the 1.46 match). Doc-first: docs/01 §2.4 [CLEARED],
QUESTIONS Q3/Q5 RESOLVED, derivations index/nav, Fields.ElectronClosure
docstring. build_docs_local.jl green.

The companion Hirshman-Sigmar k ~= -1.173 remains deferred (own derivation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…o frame convention)

Completed the gradient drive by re-reading I19 Eq. 29 first-hand. CORRECTION:
the earlier draft misread the ratio as omega_si^T/omega_ci (=> would need the
frame convention); it is omega_si^T/omega_si = 1 + (vhat^2-3/2)*eta_i, a
dimensionless TEMPERATURE factor, not a frequency ratio. So NO frame convention
is needed. The drive is the standard neoclassical p_phi*F'_Mi, imposed as the
FAR-FIELD boundary condition (master eq is homogeneous -- I19 Formulation A), not
an interior source.

Cleared: Operators.GradientDrive = 0 (zero interior source) and
Configure.gradient_far_field builds g_far = x*inv_Ln0*[1+(E-3/2)*eta_i]
(Phi_far = 0 at omega_E=0), with a new Level0Physics.eta_i. Both :gradient_drive
and :far_field moved gated->cleared; drive/bc dropped from GatedLevel0Inputs.

physics-verifier PASS -- re-read the PDF first-hand and CONFIRMED Eq. 29 is
omega_si^T/omega_si (not omega_ci), validating the correction; far-field form,
zero source, Phi_far=0, no frame convention, no guessed literal all checked. 1511
islands assertions green (the assembly now solves with the physical far field).
Doc-first: gradient-drive.md signed off, docs/01 §2, QUESTIONS Q5, numerics.md,
derivations index/nav. build_docs_local.jl green.

Remaining gated (Q5): E×B coupling, collision magnitude <nu_ii>_u, orbit-averaged
pitch measure. Plus the deferred k ~= -1.173.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…STIONS Q5)

Captured the E×B derivation core for the next session: c_E = (1/2)<1/vhat_par>_theta
(the orbit transit-time weight, NOT frame-entangled), plus the three wrinkles to
finish carefully -- velocity-dependent coefficient (operator change), the new
<1/sqrt(1-yb)> orbit bracket, and the passing-vs-trapped sigma-parity. Paused
before implementing to give the sigma subtlety a fresh look rather than
end-of-session attention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…, trapped ≡ 0)

Derive and clear the E×B coupling c_E = ½⟨1/v̂_∥⟩_θ (human sign-off,
derivation exb-coupling.md). Matching the master-eq E×B braces to the
ExBDrift Poisson bracket in the c_D=ω̂_D normalization (÷ −m ρ̂_θi, ρ̂_θi
cancels — no new physics parameter) fixes the coefficient with no sign
freedom.

σ-parity (the crux): passing (y<y_c) is σ-odd c_E = (σ/2√E)B₁(y) with a new
orbit bracket B₁(y)=⟨1/√(1−yb)⟩_θ; trapped (y>y_c) is identically 0 — the
σ-odd 1/v̂_∥ cancels between the two banana legs under Σ_σ. Required (not
chosen) by the published drift-island label S ∝ p̂ for trapped (docs/01 §2.2).
E×B is a passing-particle effect, like island-streaming.

- Coefficients.orbit_average_exb_bracket — B₁(y), passing-only, same y_c-layer
  handling as the drift G bracket.
- Configure.exb_coupling_table — c_E[ix,iξ,iy,iE,iσ], passing-only Θ(y_c−y).
- Operators.ExBDrift generalized to a velocity-dependent array coefficient
  (scalar path retained for manufactured tests).
- :exb moved gated→cleared; c_E removed from GatedLevel0Inputs.

physics-verifier PASS; 1566 islands assertions green; build_docs_local.jl
green. The M2c structural-solve assertion switched to the grid-independent
max-norm (04 §5 criterion): the now-active E×B spreads a ~1e-8 residual across
~N unknowns, inflating the √N L2 norm past 1e-7 (per-equation residual 4.5e-8;
not a physics change). Doc-first: docs/01 §2 (+ fixed the §2 line-107
orbit-average convention to match both cleared code paths), QUESTIONS Q5,
numerics.md §2/§8, derivations index/nav.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…ntum-restoring ⟨ν̂_ii⟩_u)

Derive and clear the two remaining pieces of the Level-0 collision magnitude
(human sign-off, derivation collision-magnitude.md), completing the deferred
sub-item of the signed-off collision-operator derivation (§7).

Read L23 Eqs. 4.1.4–4.1.6 (p. 87–88) first-hand and derived the
momentum-restoring speed average

  ⟨ν̂_ii⟩_u = (4ε^{3/2}ν_★/3√π)(√2 − ln(1+√2))

from L23's reduced integrand: the reduction u⁴ν̃_jj = u·erf − erf/2u + e^{−u²}/√π
plus three standard integrals (∫u e^{−u²}erf = 1/2√2, ∫e^{−2u²} = ½√(π/2),
∫u⁻¹e^{−u²}erf = ln(1+√2) = arcsinh(1)). Verified independently (QuadGK): all
three integrals and the u⁴ν̃ reduction exact to 15 digits, ⟨1⟩_u = 1
(normalized), and the full value reproduces L23's own unit-test 1.267537e-4
(ε=0.1, ν_★=0.01) to all 7 digits.

- Coefficients.momentum_restoring_average — the ⟨ν̂_ii⟩_u constant (the
  restoring operator term is a separate future addition; this clears its
  magnitude).
- Level0Physics.nu_star — the banana-regime collisionality ν_★, a scenario scan
  input (Decision D7).
- Configure builds nu_tilde = ε^{3/2}ν_★ (the already-signed-off §4
  normalization) and wires it into the collision coefficient; :nu_tilde moved
  gated→cleared; nu_tilde removed from GatedLevel0Inputs (now B_profile-only).

This un-gates the collision operator magnitude — only the orbit-averaged pitch
measure B_profile remains gated at Level 0. physics-verifier PASS; 1577 islands
assertions green; build_docs_local.jl green. Doc-first: docs/01 §2.3,
QUESTIONS Q5, numerics.md §2/§8, collision-operator.md §7, derivations
index/nav.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…or (5/6 terms, last operator gate)

Clear the full orbit-averaged collision operator (human sign-off, derivation
orbit-averaged-collision.md) — the last Level-0 operator gate. Reading L23
Eq. 2.3.47 / appendix 8.3.2 first-hand showed "B_profile" is the tip of a
six-term operator. Implement the five differential terms in the code
normalization ÷(−m ρ̂_θi):

- σ-odd mimetic PITCH DIFFUSION D+E — exact y-divergence ∂_y(P_oa ∂_y) with
  P_oa = y⟨√(1−yb)⟩_θ (orbit-averaged, replacing the local single-B
  placeholder), flat measure (divergence identity verified to 1e-11);
- σ-even ∂_x DRAG (A); σ-odd ∂²_x NEOCLASSICAL diffusion (B, uses ⟨1/√(1−yb)⟩_θ);
  σ-even ∂²_xy CROSS (C).

Key fidelity fixes: the pitch diffusion is σ-ODD (the 1/v̂_∥ transit weight, like
ω̂_D/c_E) — a correction of the former σ-even placeholder; and the collision
coefficients are POSITIVE (÷(−m ρ̂_θi) of L23's leading −, matching the streaming
anchor a_ξ=+(x/L̂q)Θ/ρ̂θ) — the physics-verifier caught an initial sign error and
confirmed the fix. The collision terms carry an explicit 1/(m ρ̂_θi) (m does not
cancel as it does for the drift), so m is a new Level0Physics scenario input.

- Coefficients.orbit_average_pitch_brackets — (S=⟨√(1−yb)⟩, T=⟨1/√(1−yb)⟩).
- Configure.{pitch_diffusivity_profile, pitch_collision_coefficient,
  collisional_drag_coefficient, neoclassical_diffusion_coefficient,
  collisional_cross_coefficient}.
- Operators.{CollisionalDrag, NeoclassicalDiffusion, CollisionalCross} + kernels;
  FarFieldConditions.forbidden_y pins g=0 in the no-particle region.
- GatedLevel0Inputs / level0_placeholders removed — no gated kinetic inputs
  remain; configure_level0 takes no gated argument (Q5 fully cleared).

physics-verifier PASS (after the sign fix); 1595 islands assertions green
(node-for-node coefficient/σ-parity checks + an A4 conservation/entropy gate on
the shipped P_oa); build_docs_local.jl green. Doc-first: docs/01 §2.3,
QUESTIONS Q5, numerics.md §2/§8, derivations index/nav; B5 benchmark de-gated.

Two collision follow-ups remain (not gates on the differential solve): the
nonlocal momentum-restoring term F (magnitude ⟨ν̂_ii⟩_u already cleared), and
repointing Verify.jl's assembled-MMS harness to the new operators.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
… on the gated parallel-flow moment weight)

Investigating the sixth collision term (momentum-restoring F,
2ν̂_ii(1+ε)Ū_∥ᵢ(ĝ+pF̂′)F̂_M) surfaced that it is blocked on a gated
normalization, so it is escalated rather than guessed (per the [VERIFY]
policy).

The structure is clear (L23 Eq. 2.3.47/8.3.17): a nonlocal operator forming the
parallel-flow moment Ū_∥ᵢ(x,ξ) = (1/√π⟨ν̂_ii⟩_u) Σ_σ σ ∫du u³ν̂_ii ∫dy ĝ, then
redistributing 2ν̂_ii(1+ε)Ū F̂_M (σ-even, positive sign per §3). Its magnitude
⟨ν̂_ii⟩_u is already cleared (collision-magnitude.md).

The blocker: Ū is exactly the parallel-flow velocity moment whose weight
W(y,E,σ) (the v̂_∥-structure) is [VERIFY]-gated (QUESTIONS Q3) —
Moments.parallel_current! and Operators.jl:185 already flag the field-particle
piece as Q3-gated. Compounding: the energy grid is Gauss-Laguerre
(Σ wₑ f ≈ ∫ f e^{−E} dE, Maxwellian folded in), but Ū's moment is a plain
∫du u³ν̂_ii, so the g↔F̂_M convention must be pinned first. Escalated to
QUESTIONS Q5; nothing entered src/ for F.

Doc-only: QUESTIONS Q5 (new F item), orbit-averaged-collision.md §9 status.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
… + parallel-flow weight W

Clearing Q3's parallel-flow weight W surfaced (escalated as Q6) that the code's
velocity_moment!/weighted_moment! used a flat measure missing the physical ∫d³v
Jacobians (√E/2 speed, 1/√(1−yb) pitch) — and that the already-cleared QN
density δn̄_i used that flat moment. The user chose the physical ∫d³v with the
flux-surface b. Derived and cleared (human sign-off, velocity-moment-measure.md):

- physical_velocity_weights: the √E/2 speed Jacobian (folded into
  Gauss-Laguerre) and the 1/√(1−y·b_min) pitch Jacobian (b_min=(1−ε)/(1+ε), an
  exact singular-weight quadrature = the IinvB edge; forbidden region zeroed,
  Σwy_phys = 2/b_min exactly).
- parallel_flow_weight: W = v̂_∥ = σ√E√(1−y·b_min) (clears Q3's W); its √(1−yb)
  cancels the pitch Jacobian so J̄_∥ is regular.
- velocity_moment!/weighted_moment! gained wy/wE kwargs (default flat — M1/M2
  manufactured tests untouched); Operators.Quasineutrality carries the physical
  weights, so δn̄_i is now the physical moment (max|Φ| shifted 5.7→4.5, the
  approved QN revision; closure algebra α/S unchanged).

This resolves Q6, clears Q3's W (un-gating Moments.parallel_current! → the Δ
outputs), and UNBLOCKS term F (Q5) — Ū is now a bounded physical moment.

physics-verifier PASS; 1596 islands assertions green (Σwy=2/b_min exact,
forbidden zeroed, W σ-odd, QN wired); build_docs_local.jl green. Doc-first:
docs/01 §3/§4, QUESTIONS Q6/Q3/Q5, Moments docstrings, derivations index/nav.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
… Level-0 collision operator is complete (6/6)

Implement the sixth and final collision term — the momentum-restoring
field-particle integral (F), the one nonlocal Level-0 term (human sign-off;
orbit-averaged-collision.md §6, unblocked by the Q6 physical ∫d³v measure).

- Operators.MomentumRestoring + apply!: forms the parallel-flow moment
  Ū(x,ξ) = (1/√π⟨ν̂_ii⟩_u){ν̂_ii v̂_∥ g}_v (physical measure; moment weight
  W = ν̂_ii·v̂_∥, σ-odd) into a new cache.Ubar scratch, then adds the σ-even
  redistribution +2ν̂_ii(1+ε)Ū/(m ρ̂_θi) (positive — ÷−m ρ̂_θi of the RHS; the
  F̂_M=e^{−E} cancels in the g=shape convention).
- Configure.momentum_restoring_term builds W, the redistribution, the physical
  weights, and inv_norm = 1/(√π⟨ν̂_ii⟩_u) from the cleared momentum_restoring_average.
- Wired into configure_level0 (9-term kinetic stack); IslandCache gained Ubar.

Linear in g (Ū is a moment), allocation-free (cache.Ubar), AD-transparent; uses
only cleared inputs. All six collision terms are now complete — no gated kinetic
physics remains.

physics-verifier PASS (traced Ū vs L23 Eq. 8.3.17 line-by-line, positive sign,
linearity, no guessed number); 1690 islands assertions green (W σ-odd,
redistribute positive, F(2g)=2F(g), nu_star=0 guard); build_docs_local.jl green.
Doc-first: docs/01 §2.3, QUESTIONS Q5, numerics.md §2/§8,
orbit-averaged-collision.md (6/6), anchor-sync marker.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
…rrent Δ outputs

Wire the physical Level-0 solve into the Δ growth/torque moments — the first
physics deliverable off the converged state (docs/01 §4). No new [VERIFY]
coefficient: assembly + diagnostics only, physics-verifier PASS.

- Moments.parallel_current! gains wy/wE kwargs (forwarded to weighted_moment!)
  so J̄_∥ carries the physical ∫d³v measure; W = v̂_∥'s √(1−y b_min) cancels the
  pitch Jacobian and J̄_∥ is regular. Defaults to the flat quadrature.
- Configure.delta_outputs(grid, phys, species, Usol, cfg): builds cleared W +
  physical measure, forms J̄_∥ from the solved bulk-ion g, projects to
  Δ_neo ≡ Δ_cos and Δ_sin with the cleared ∓μ₀R/2ψ̃ prefactors.
- Moments.channel_decomposition + grid_interpolant: the docs/01 §4 flux-surface
  split — ⟨J̄_∥⟩_Ω bootstrap+curvature channel and the Δ_pol polarization
  residual, plus the ⟨J̄_∥⟩_Ω profile (approximate diagnostic, L23 Eq. 2.5.3).

Doc-first: numerics.md §7/§8. Tests: 138 solve + 1540 configure + 5 anchor-sync
green (nodal-exact interpolant, flux-function Δ_pol→0, profile recovers f(Ω),
additive split, single-bulk contract); build_docs_local.jl green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016pUwoFRo9a5AjF8HuwcZMr
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request WIP Work in progress

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant